/*
  Copyright (C) 2011, Kyungjoo Kim
  
  This file is part of LINAL (LINear ALgebra)
  
  All rights reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.
  
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
  
  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  Also add information on how to contact you by electronic and paper mail.
  
  
  Kyungjoo Kim
  iamkyungjoo@gmail.com
*/
#ifndef LINAL_OP_INTERNAL_HXX
#define LINAL_OP_INTERNAL_HXX


namespace linal {
  // ----------------------------------------------------------------
  // ** Internal blas routines

  // * Utilities
  extern int apply_pivots_ln_internal ( FLA_Obj p, FLA_Obj A);
  extern int apply_pivots_lt_internal ( FLA_Obj p, FLA_Obj A);
  extern int apply_pivots_rn_internal ( FLA_Obj p, FLA_Obj A);
  extern int apply_pivots_rt_internal ( FLA_Obj p, FLA_Obj A);

  extern int apply_pivots_internal    ( int side, int trans, 
                                        FLA_Obj p, FLA_Obj A);

  extern int diag_internal            ( FLA_Obj A, FLA_Obj d );

  extern void reset_operation_counter ();
  extern void disp_operation_stat     (FILE *stream);

  // * BLAS
  extern int herk_internal            ( int uplo, int trans,
                                        FLA_Obj alpha, FLA_Obj A,
                                        FLA_Obj beta,  FLA_Obj C );
  extern int syrk_internal            ( int uplo, int trans,
                                        FLA_Obj alpha, FLA_Obj A,
                                        FLA_Obj beta,  FLA_Obj C );
  extern int gemm_internal            ( int transa, int transb,
                                        FLA_Obj alpha, FLA_Obj A, FLA_Obj B,
                                        FLA_Obj beta,  FLA_Obj C );
  extern int trsm_internal            ( int side, int uplo, int trans, int diag,
                                        FLA_Obj alpha, FLA_Obj A, FLA_Obj B );
  extern int trmm_internal            ( int side, int uplo, int trans, int diag,
                                        FLA_Obj alpha, FLA_Obj A, FLA_Obj B );

  // * FLAME

  extern int chol_incpiv_l_internal   ( FLA_Obj A, FLA_Obj p );
  extern int chol_incpiv_u_internal   ( FLA_Obj A, FLA_Obj p );
  extern int chol_incpiv_internal     ( int uplo, FLA_Obj A, FLA_Obj p );

  extern int ldl_nopiv_l_internal     ( FLA_Obj A );
  extern int ldl_nopiv_u_internal     ( FLA_Obj A );
  extern int ldl_nopiv_internal       ( int uplo, FLA_Obj A );

  extern int ldl_incpiv_l_internal    ( FLA_Obj A, FLA_Obj p );
  extern int ldl_incpiv_u_internal    ( FLA_Obj A, FLA_Obj p );
  extern int ldl_incpiv_internal      ( int uplo, FLA_Obj A, FLA_Obj p );
}
#endif
